package org.chatty;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStream;

import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;

import org.apache.commons.codec.binary.Base64;

public class Poster extends ThreadedByter {

	private AudioFormat audioFormat_;
	private AudioFileFormat.Type type_;
	private String href_;
	private boolean encode_ = true;

	private byte audioData_[];
	private String comment_;

	private URLConnection urlConnection_;

	public Poster( AudioFormat audioFormat, AudioFileFormat.Type type, String href, boolean encode ) {
		this.setAudioFormat( audioFormat );
		this.setType( type );
		this.setHref( href );
		this.setEncode( encode );
	}

	////

	public void setup( byte audioData[], String comment ) {
		this.setComment( comment );
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try {
			Util.write(
				audioData
				, this.getAudioFormat()
				, this.getType()
				, byteArrayOutputStream
			);
		} catch( IOException ioException ) {
			// yeah right...
		}
		this.setAudioData( byteArrayOutputStream.toByteArray() );
	}

	public void start_process() throws Exception {
		URL url = new URL( this.getHref() );
		URLConnection urlConnection = url.openConnection();
		urlConnection.setDoOutput( true );
		this.setUrlConnection( urlConnection );
	}

	// http://www.exampledepot.com/egs/java.net/Post.html
	// this really just writes in one chunk... 	
	public int process_chunk( byte buffer[] ) throws Exception {
		if ( this.getEncode() ) {
			String enc = "UTF-8";
			java.io.OutputStreamWriter outputStreamWriter = new java.io.OutputStreamWriter(
				this.getUrlConnection().getOutputStream(), enc
			);
			System.out.println( "encode data" );

			String data = ( ""
				+ URLEncoder.encode( "data", enc )
				+ "="
				+ URLEncoder.encode( new String( Base64.encodeBase64( this.getAudioData() ) ), enc )
				+ "&"
				+ URLEncoder.encode( "comment", enc )
				+ "="
				+ URLEncoder.encode( this.getComment().replace( "\\s", " " ) )
			);

			outputStreamWriter.write( data.toCharArray(), 0, data.length() );
			outputStreamWriter.flush();
			outputStreamWriter.close();
		} else {
			OutputStream outputStream = this.getUrlConnection().getOutputStream();
			System.out.println( "raw data" );
			outputStream.write( this.getAudioData() );
			outputStream.flush();
			outputStream.close();
		}
		return -1;

/*
		OutputStream outputStream = this.getUrlConnection().getOutputStream();
		if ( this.getEncode() ) {
			System.out.println( "encode data" );
			outputStream.write( "data=".getBytes() );
			outputStream.write( Base64.encodeBase64( this.getAudioData() ) );
		} else {
			System.out.println( "raw data" );
			outputStream.write( this.getAudioData() );
		}
		outputStream.flush();
		outputStream.close();
		return -1;
*/
	}

	public void stop_process() throws Exception {
		BufferedReader bufferedReader = new BufferedReader(
			new InputStreamReader( this.getUrlConnection().getInputStream() )
		);
		String line;
		while ( null != ( line = bufferedReader.readLine() ) ) {
			// TODO: process line...
		}
		bufferedReader.close();
	}

	//// boilerplate

	public boolean getEncode() {
		return this.encode_;
	}

	public void setEncode( boolean encode ) {
		this.encode_ = encode;
	}

	public String getHref() {
		return this.href_;
	}

	public void setHref( String href ) {
		this.href_ = href;
	}

	public AudioFormat getAudioFormat() {
		return this.audioFormat_;
	}

	public void setAudioFormat( AudioFormat audioFormat ) {
		this.audioFormat_ = audioFormat;
	}

	public AudioFileFormat.Type getType() {
		return this.type_;
	}

	public void setType( AudioFileFormat.Type type ) {
		this.type_ = type;
	}

	public byte[] getAudioData() {
		return this.audioData_;
	}

	public void setAudioData( byte audioData[] ) {
		this.audioData_ = audioData;
	}

	public URLConnection getUrlConnection() {
		return this.urlConnection_;
	}

	public void setUrlConnection( URLConnection urlConnection ) {
		this.urlConnection_ = urlConnection;
	}

	public String getComment() {
		return this.comment_;
	}

	public void setComment( String comment ) {
		this.comment_ = comment;
	}
};
